#!/usr/bin/ruby

files = ["OCR","OCR.PCA95","OCR.PCA70"]
alphabet = {"A",0,"B",0,"C",0,"D",0,"E",0,"F",0,"G",0,"H",0,"I",0,"J",0,"K",0,"L",0,"M",0,"N",0,"O",0,"P",0,"Q",0,"R",0,"S",0,"T",0,"U",0,"V",0,"W",0,"X",0,"Y",0,"Z",0}

files.each { |f|
    infile = File.new("input/" + f + ".arff", "r")
    outfilebin = File.new("output/binary_class/" + f  + ".pat", "w")
    outfilebin_train = File.new("output/binary_class/" + f  + ".Train.pat", "w")
    outfilebin_test = File.new("output/binary_class/" + f  + ".Test.pat", "w")
    outfile = File.new("output/numeric_class/" + f + ".pat", "w")
    outfile_train = File.new("output/numeric_class/" + f  + ".Train.pat", "w")
    outfile_test = File.new("output/numeric_class/" + f  + ".Test.pat", "w")
    
    # Find min and max for each input parameter
    process = false
    total = 0
    min = []
    max = []
    infile.each { |i|
	    if (process) then
	        v = i.split(",")

            for j in 0..(v.length - 1 - 1) # Do not process class (last column)
                if max[j].nil? or max[j] < v[j].to_f then
                    max[j] = v[j].to_f
                end
                if min[j].nil? or min[j] > v[j].to_f then
                    min[j] = v[j].to_f
                end
            end
            total = total + 1
	    end
	    if (i[0,5] == "@data") then
		    process = true
	    end
    }
    
    #puts "max: " + max.join(" ")
    #puts "min: " + min.join(" ")
    
    infile.close
    infile = File.new("input/" + f + ".arff", "r")
    
    # Headers
    outfile.write("SNNS pattern definition file V3.2\n")
    outfile.write("generated at Mon Jan 10 15:58:23 2010\n\n\n")
    outfile.write("No. of patterns : " + total.to_s + "\n")
    outfile.write("No. of input units : " + max.length.to_s + "\n")
    outfile.write("No. of output units : " + "1" + "\n\n")
    outfile_train.write("SNNS pattern definition file V3.2\n")
    outfile_train.write("generated at Mon Jan 10 15:58:23 2010\n\n\n")
    outfile_train.write("No. of patterns : " + (total * 0.70).round.to_s + "\n")
    outfile_train.write("No. of input units : " + max.length.to_s + "\n")
    outfile_train.write("No. of output units : " + "1" + "\n\n")
    outfile_test.write("SNNS pattern definition file V3.2\n")
    outfile_test.write("generated at Mon Jan 10 15:58:23 2010\n\n\n")
    outfile_test.write("No. of patterns : " + (total - (total * 0.70).round).to_s + "\n")
    outfile_test.write("No. of input units : " + max.length.to_s + "\n")
    outfile_test.write("No. of output units : " + "1" + "\n\n")
    outfilebin.write("SNNS pattern definition file V3.2\n")
    outfilebin.write("generated at Mon Jan 10 15:58:23 2010\n\n\n")
    outfilebin.write("No. of patterns : " + total.to_s + "\n")
    outfilebin.write("No. of input units : " + max.length.to_s + "\n")
    outfilebin.write("No. of output units : " + "26" + "\n\n")
    outfilebin_train.write("SNNS pattern definition file V3.2\n")
    outfilebin_train.write("generated at Mon Jan 10 15:58:23 2010\n\n\n")
    outfilebin_train.write("No. of patterns : " + (total * 0.70).round.to_s + "\n")
    outfilebin_train.write("No. of input units : " + max.length.to_s + "\n")
    outfilebin_train.write("No. of output units : " + "26" + "\n\n")
    outfilebin_test.write("SNNS pattern definition file V3.2\n")
    outfilebin_test.write("generated at Mon Jan 10 15:58:23 2010\n\n\n")
    outfilebin_test.write("No. of patterns : " + (total - (total * 0.70).round).to_s + "\n")
    outfilebin_test.write("No. of input units : " + max.length.to_s + "\n")
    outfilebin_test.write("No. of output units : " + "26" + "\n\n")


    process = false
    count = 0
    infile.each { |i|
        if (process) then
            v = i.split(",")
            # Rescale/Normalize between 0..1
            for j in 0..(v.length - 1 - 1) # Do not process class (last column)
                if (max[j].to_f - min[j].to_f) != 0 then
                    v[j] = (v[j].to_f - min[j].to_f) / (max[j].to_f - min[j].to_f)
                end
            end
            
            letter = v.pop # Extract and remove from vector the class (last column)
		    # Binary array with order: V K W L A X M B Y N C Z O D P E Q F R G S H T I U J
		    alphabet[letter[0,1]] = 1
		    # Numerical value:
		    value = 0
            for j in 0..26
                if alphabet.keys[j] == letter[0,1] then
                    # Order: V K W L A X M B Y N C Z O D P E Q F R G S H T I U J
                    #        0.................................................1
                    #         with increments of 0.04
                    value = j.to_f / 25 # From 0..25
                    break
                end
            end
            
            outfilebin.write v.join(" ") + " " + alphabet.values.join(" ") + "\n"
            outfile.write v.join(" ") + " " + value.to_s + "\n"
            if count < (total * 0.70).round then
                outfilebin_train.write v.join(" ") + " " + alphabet.values.join(" ") + "\n"
                outfile_train.write v.join(" ") + " " + value.to_s + "\n"
            else
                outfilebin_test.write v.join(" ") + " " + alphabet.values.join(" ") + "\n"
                outfile_test.write v.join(" ") + " " + value.to_s + "\n"
            end
            
            alphabet[letter[0,1]] = 0
            count = count + 1
        end
        if (i[0,5] == "@data") then
		    process = true
	    end
    }
    
    infile.close
    outfilebin.close
    outfilebin_train.close
    outfilebin_test.close
    outfile.close
    outfile_train.close
    outfile_test.close
    
}

# Print conversion table
#        V K W L A X M B Y N C Z O D P E Q F R G S H T I U J
#        0.................................................1
outfiletable = File.new("output/conversion_table.tx", "w")
outfiletable.write "-----------------------------------------------------------------------------------\n"
outfiletable.write "* Conversion table: Class, numeric and binary values                              *\n"
outfiletable.write "-----------------------------------------------------------------------------------\n"
outfiletable.write "Class\t\tNum.\t\t" + alphabet.keys.join(" ") + "\n"
outfiletable.write "-----------------------------------------------------------------------------------\n"
count = 0.0
i = 0
while i < 26
    alphabet[alphabet.keys[i]] = 1
    outfiletable.write alphabet.keys[i] + "\t=\t" + count.to_s + "\t=\t" + alphabet.values.join(" ") + "\n"
    alphabet[alphabet.keys[i]] = 0
    count = count + 0.04
    i = i + 1
end
outfiletable.write "-----------------------------------------------------------------------------------\n"


